package cn.tedu.charging.order.service.impl;

import cn.tedu.charging.order.common.GunStatusConstants;
import cn.tedu.charging.order.feign.DeviceClient;
import cn.tedu.charging.order.feign.UserClient;
import cn.tedu.charging.order.service.OrderService;
import cn.tedu.charging.order.pojo.param.OrderAddParam;
import cn.tedu.common.JsonResult;
import cn.tedu.common.pojo.param.GunStatusUpdateParam;
import cn.tedu.common.pojo.vo.StationInfoVO;
import cn.tedu.common.pojo.vo.UserInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.Random;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private UserClient userClient;
    @Autowired
    private DeviceClient deviceClient;


    /**
     * 通过枪id获取场站信息
     * @param gunId
     * @return
     */
    private StationInfoVO getStationInfo(Integer gunId) {
        return deviceClient.getStationInfo(gunId).getData();
    }


    /**
     * 修改枪的状态
     * @param gunId
     * @param status
     * @return
     */
    public Boolean updateGunStatus(Integer gunId,  Integer status){
        GunStatusUpdateParam param = new GunStatusUpdateParam();
        param.setGunId(gunId);
        param.setStatus(status);
        return deviceClient.updateGunStatus(param).getData();
    }

    /**
     *  1. 生成 订单编号 生成的逻辑
     *
     *  2. 修改 充电枪 的 状态 为 使用中 (微服务架构  订单服务调用 设备服务 服务之间通信)
     *  3. 获取 用户信息 （车辆id）  (微服务架构  订单服务 调用 用户服务 服务之间通信)
     *  4. 获取 服务信息/设备信息 (场站信息 和 设备信息 充电站id, 运营商id ... ）    (微服务架构  订单服务 调用 设备服务 服务之间通信)
     *
     *  5. 订单服务 给 设备 发送开始充电指令  (物联网 订单服务 调用 硬件充电桩设备 服务与 设备之间通信）
     *  @param orderAddParam
     *  @return
     */

    @Override
    public String createOrder(OrderAddParam orderAddParam) {
        log.debug("创建订单-orderService:入参:{}",orderAddParam);

        //1 生成订单号
        log.debug("创建订单-orderService:生成订单号");
        String orderNo = getOrderNo();
        log.debug("创建订单-orderService:生成订单号:{}",orderNo);

        //2 修改 充电枪 的 状态 为 使用中 (微服务架构  订单服务调用 设备服务 服务之间通信)
        Integer gunId = orderAddParam.getGunId();
        Integer using = GunStatusConstants.GUN_STATUS_USING;
        log.debug("创建订单-orderService:修改枪状态入参:{},{}",gunId,using);
        Boolean gunStatusUpdate = updateGunStatus(gunId, using);
        log.debug("创建订单-orderService:修改枪状态入参:{},{},出参:{}",gunId,using,gunStatusUpdate);

        //3 获取 用户信息 （车辆id）
        Integer userId = orderAddParam.getUserId();
        log.debug("创建订单-orderService:获取用户信息入参:{}",userId);
        UserInfoVO userInfoVO = getUserInfoByOpenFeign(orderAddParam.getUserId());
        log.debug("创建订单-orderService:获取用户信息入参:{},出参:{}",userId,userInfoVO);

        //4 获取 服务信息/设备信息
        log.debug("创建订单-orderService:获取服务信息/设备信息入参:{}",gunId);
        StationInfoVO stationInfoVO = getStationInfo(gunId);
        log.debug("创建订单-orderService:获取服务信息/设备信息入参:{},出参:{}",gunId,stationInfoVO);


        log.debug("创建订单-orderService:入参:{},出参:{}",orderAddParam,orderNo);
        return orderNo;
    }

    /**
     * 通过RestTemplate 调用用户服务的 获取用户详情接口
     * @param userId
     * @return
     */
    private UserInfoVO getUserInfoByUserId(Integer userId) {
        //用户服务的获取用户信息接口地址
        //String url = "http://localhost:7070/user/info/" + userId;
        //String url = "http://localhost:7070/user/info/{userId}";
        String randomUrl = getRandomUrl();
        log.debug("随机获取用户服务的地址：{}",randomUrl);

        ParameterizedTypeReference<JsonResult<UserInfoVO>> typeRef =
                new ParameterizedTypeReference<JsonResult<UserInfoVO>>() {
                };

        ResponseEntity<JsonResult<UserInfoVO>> entity =
                restTemplate.exchange(randomUrl,
                        HttpMethod.GET,
                        null, typeRef,userId);
        JsonResult<UserInfoVO> body = entity.getBody();
        return  body.getData();
    }

    /**
     * 生成订单号
     * @return
     */
    private String getOrderNo(){
        return "666";
    }

    /**
     * 随机获取用户服务地址 (负载均衡)
     * 1. 把用户服务的 URL 放到数组
     * 2. 获取 随机数 通过JavaAPI Random
     * 3. 把随机数作为数组的下标,去数组 通过 下标 获取 用户服务URL
     * 4. 通过URL调用用户服务
     * @return
     */
    private String getRandomUrl() {
        String url = "http://localhost:7070/user/info/{userId}";
        String url1 = "http://localhost:7071/user/info/{userId}";
        String url2 = "http://localhost:7072/user/info/{userId}";

        String[] urls = new String[]{url,url1,url2};
        Random random = new Random();
        int index = random.nextInt(urls.length);
        return urls[index];
    }

    /**
     * 订单服务
     *  通过 open-feign 服务之间通信的工具
     *  注册中心 服务注册 和 服务发现
     *  LB 负载均衡
     * 调用用户服务
     * @param userId
     * @return
     */
    private UserInfoVO getUserInfoByOpenFeign(Integer userId) {
        return userClient.getUserInfo(userId).getData();
    }



}
